Primero, crearemos una de las tablas de nuestro ejemplo. Esta tabla, COFFEES, contiene la informaci�n esencial sobre los caf�s vendidos en "The Coffee Break", incluyendo los nombres de los caf�s, sus precios, el n�mero de libras vendidas la semana actual, y el n�mero de libras vendidas hasta la fecha. Aqu� puedes ver la tabla COFFEES, que describiremos m�s adelante.
| COF_NAME | SUP_ID | PRICE | SALES | TOTAL |
|---|---|---|---|---|
| Colombian | 101 | 7.99 | 0 | 0 |
| French_Roast | 49 | 8.99 | 0 | 0 |
| Espresso | 150 | 9.99 | 0 | 0 |
| Colombian_Decaf | 101 | 8.99 | 0 | 0 |
| French_Roast_Decaf | 49 | 9.99 | 0 | 0 |
La columna que almacena el nombre del caf� es COF_NAME, y contiene valores con el tipo VARCHAR de SQL y una longitud m�xima de 32 caracteres. Como utilizamos nombres diferentes para cada tipo de caf� vendido, el nombre ser� un �nico identificador para un caf� particular y por lo tanto puede servir como clave primaria. La segunda colunma, llamada SUP_ID, contiene un n�mero que identifica al suministrador del caf�; este n�mero ser� un tipo INTEGER de SQL. La tercera columna, llamada PRICE, almacena valores del tipo FLOAT de SQL porque necesita contener valores decimales. (Observa que el dinero normalmente se almacena en un tipo DECIMAL o NUMERIC de SQL, pero debido a las diferencias entre controladores de bases de datos y para evitar la incompatibilidad con viejas versiones de JDBC, utilizamos el tipo m�s est�ndard FLOAT.) La columna llamada SALES almacena valores del tipo INTEGER de SQL e indica el n�mero de libras vendidas durante la semana actual. La columna final, TOTAL,contiene otro valor INTEGER de SQL que contiene el n�mero total de libras vendidas hasta la fecha.
SUPPLIERS, la segunda tabla de nuesta base de datos, tiene informaci�n sobre cada uno de los suministradores.
| SUP_ID | SUP_NAME | STREET | CITY | STATE | ZIP |
|---|---|---|---|---|---|
| 101 | Acme, Inc. | 99 Market Street | Groundsville | CA | 95199 |
| 49 | Superior Coffee | 1 Party Place | Mendocino | CA | 95460 |
| 150 | The High Ground | 100 Coffee Lane | Meadows | CA | 93966 |
Las tablas COFFEES y SUPPLIERS contienen la columna SUP_ID, lo que significa que estas dos tablas pueden utilizarse en sentencias SELECT para obtener datos basados en la informaci�n de ambas tablas. La columna SUP_ID es la clave primaria de la tabla SUPPLIERS, y por lo tanto, es un identificador �nico para cada uno de los suministradores de caf�. En la tabla COFFEES, SUP_ID es llamada clave extranjera. (Se puede pensar en una clave extranjera en el sentido en que es importada desde otra tabla). Observa que cada n�mero SUP_ID aparece s�lo una vez en la tabla SUPPLIERS; esto es necesario para ser una clave primaria. Sin embargo, en la tabla COFFEES, donde es una clave extranjera, es perfectamente correcto que haya n�meros duplicados de SUP_ID porque un suministrador puede vender varios tipos de caf�. M�s adelante en este cap�tulo podremos ver c�mo utilizar claves primarias y extranjeras en una sentencia SELECT.
La siguiente sentencia SQL crea la tabla COFFEES. Las entradas dentro de los par�ntesis exteriores consisten en el nombre de una columna seguido por un espacio y el tipo SQL que se va a almacenar en esa columna. Una coma separa la entrada de una columna (que consiste en el nombre de la columna y el tipo SQL) de otra. El tipo VARCHAR se crea con una longitud m�xima, por eso toma un par�metro que indica la longitud m�xima. El par�metro debe estar entre par�ntesis siguiendo al tipo. La sentencia SQL mostrada aqu�, por ejemplo, espec�fica que los nombres de la columna COF-NAME pueden tener hasta 32 caracteres de longitud.
CREATE TABLE COFFEES (COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, SALES INTEGER, TOTAL INTEGER)
Este c�digo no termina con un terminador de sentecia de un controlador de base de datos, que puede variar de un controlador a otro. Por ejemplo, Oracle utiliza un punto y coma (;) para finalizar una sentencia, y Sybase utiliza la plabra go. El driver que estamos utilizado proporcionar� autom�ticamente el terminador de setencia apropiado, y no necesitaremos introducirlo en nuestro c�digo JDBC.
Otra cosa que deb�amos apuntar sobre las sentencias SQL es su forma. En la sentencia CREATE TABLE, las palabras clave se han imprimido en letras m�yusculas, y cada �tem en una l�nea separada. SQL no requiere nada de esto, estas convenciones son s�lo para una f�cil lectura. El est�ndard SQL dice que la palabras claves no son sensibles a las may�sculas, as�, por ejemplo, la anterior sentencia SELECT pude escribirse de varias formas. Y como ejemplo, estas dos versiones son equivalentes en lo que concierne a SQL.
SELECT First_Name, Last_Name FROM Employees WHERE Last_Name LIKE "Washington" select First_Name, Last_Name from Employees where Last_Name like "Washington"
Sin embargo, el material entre comillas si es sensible a las ma�usculas: en el nombre "Washington", "W" debe estar en ma�uscula y el resto de las letras en min�scula.
Los requerimientos pueden variar de un controlador de base de datos a otro cuando se trada de nombres de identificadores. Por ejemplo, algunos controladores, requieren que los nombres de columna y de tabla se�n exactamente los mismos que se crearon en las sentencias CREATE y TABLE, mientras que otros controladores no lo necesitan. Para asegurarnos, utilizaremos may�sculas para identificadores como COFFEES y SUPPLIERS porque as� es como los definimos.
Hasta ahora hemos escrito la sentencia SQL que crea la tabla COFFEES. Ahora le pondremos comillas (crearemos un string) y asignaremos el string a la variable createTableCoffees para poder utilizarla en nuestro c�digo JDBC m�s adelante. Como hemos visto, al controlador de base de datos no le importa si las l�neas est�n divididas, pero en el lenguaje Java, un objeto String que se extienda m�s all� de una l�nea no ser� compilado. Consecuentemente, cuando estamos entregando cadenas, necesitamos encerrar cada l�nea entre comillas y utilizar el signo m�s (+) para concatenarlas.
String createTableCoffees = "CREATE TABLE COFFEES " + "(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, " + "SALES INTEGER, TOTAL INTEGER)";
Los tipos de datos que hemos utilizado en nuestras sentencias CREATE y TABLE son tipos gen�ricos SQL (tambi�n llamados tipos JDBC) que est�n definidos en la clase java.sql.Types. Los controladores de bases de datos generalmente utilizan estos tipos est�ndards, por eso cuando llegue el momento de probar alguna aplicaci�n, s�lo podremos utilizar la aplicaci�n CreateCoffees.java, que utiliza las sentencias CREATE y TABLE. Si tu controlador utiliza sus propios nombres de tipos, te suministrarermos m�s adelante una aplicaci�n que hace eso.
Sin embargo, antes de ejecutar alguna aplicaci�n, veremos lo m�s b�sico sobre el JDBC.
�Crear sentencias JDBC
Un objeto Statement es el que env�a nuestras sentencias SQL al controlador de la base de datos. Simplemente creamos un objeto Statement y lo ejecutamos, suministando el m�todo SQL apropiado con la sentencia SQL que queremos enviar. Para una sentencia SELECT, el m�todo a ejecutar es executeQuery. Para sentencias que crean o modifican tablas, el m�todo a utilizar es executeUpdate.
Se toma un ejemplar de una conexi�n activa para crear un objeto Statement. En el siguiente ejemplo, utilizamos nuestro objeto Connection: con para crear el objeto Statement: stmt.
Statement stmt = con.createStatement();
En este momento stmt existe, pero no tiene ninguna sentencia SQL que pasarle al controlador de la base de datos. Necesitamos suministrarle el metodo que utilizaremos para ejecutar stmt. Por ejemplo, en el siguiente fragmento de c�digo, suministramos executeUpdate con la sentencia SQL del ejemplo anterior.
stmt.executeUpdate("CREATE TABLE COFFEES " +
"(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, " +
"SALES INTEGER, TOTAL INTEGER)");
Coma ya hab�amos creado un String con la sentencia SQL y lo hab�amos llamado createTableCoffees, podr�amos haber escrito el c�digo de esta forma alternativa.
stmt.executeUpdate(createTableCoffees);
�Ejecutar Sentencias
Utilizamos el m�todo executeUpdate porque la sentencia SQL contenida en createTableCoffees es una sentencia DDL (data definition language). Las sentencias que crean, modifican o eliminan tablas son todas ejemplos de sentencias DDL y se ejecutan con el m�todo executeUpdate. C�mo se podr�a esperar de su nombre, el m�todo executeUpdate tambi�n se utiliza para ejecutar sentencias SQL que actualizan un tabla. En la pr�ctica executeUpdate se utiliza m�s frecuentemente para actualizar tablas que para crearlas porque una tabla se crea s�lo una vez, pero se puede actualizar muchas veces.
El m�todo m�s utilizado para ejecutar sentencias SQL es executeQuery. Este m�todo se utiliza para ejecutar sentencias SELECT, que comprenden la amplia mayor�a de las sentencias SQL. Pronto veremos como utilizar este m�todo.
�Introducir Datos en una Tabla
Hemos visto como crear la tabla COFFEES especificando los nombres de columnas y los tipos de datos almacenados en esas columnas, pero esto s�lo configura la estructura de la tabla. La tabla no contiene datos todav�a. Introduciremos datos en nuestra tabla una fila cada vez, suministrando la informaci�n a almacenar en cada columna de la fila. Observa que los valores insertados en las columnas se listan en el mismo orden en que se declararon las columnas cuando se cre� la tabla, que es el orden por defecto.
El siguiente c�digo isnerta una fila de datos con Colombian en la columna COF_NAME, 101 en SUP_ID, 7.99 en PRICE, 0 en SALES, y 0 en TOTAL. (Como acabamos de inaugurar "The Coffee Break", la cantidad vendida durante la semana y la cantidad total son cero para todos los caf�s). Al igual que hicimos con el c�digo que creaba la tabla COFFEES, crearemos un objeto Statement y lo ejecutaremos utilizando el m�todo executeUpdate.
Como la sentencia SQL es damasiado larga como para entrar en una s�la l�nea, la hemos dividido en dos strings concaten�ndolas mediante un signo m�s (+) para que puedan compilarse. Presta especial atenci�n a la necesidad de un espacio entre COFFEES y VALUES. Este espacio debe estar dentro de las comillas y debe estar despu�s de COFFEES y antes de VALUES; sin un espacio, la sentencia SQL ser�a le�da err�neamente como "INSERT INTO COFFEESVALUES . . ." y el controlador de la base de datos buscar�a la tablaCOFFEESVALUES. Observa tambi�n que utilizamos comilla simples alrededor del nombre del caf� porque est� anidado dentro de las comillas dobles. Para la mayor�a de controladores de bases de datos, la regla general es alternar comillas dobles y simples para indicar anidaci�n.
Statement stmt = con.createStatement();
stmt.executeUpdate(
"INSERT INTO COFFEES " +
"VALUES ('Colombian', 101, 7.99, 0, 0)");
El siguiente c�digo inserta una segunda l�nea dentro de la tabla COFFEES. Observa que hemos reutilizado el objeto Statement: stmt en vez de tener que crear uno nuevo para cada ejecuci�n.
stmt.executeUpdate("INSERT INTO COFFEES " +
"VALUES ('French_Roast', 49, 8.99, 0, 0)");
Los valores de las siguientes filas se pueden insertar de esta forma.
stmt.executeUpdate("INSERT INTO COFFEES " +
"VALUES ('Espresso', 150, 9.99, 0, 0)");
stmt.executeUpdate("INSERT INTO COFFEES " +
"VALUES ('Colombian_Decaf', 101, 8.99, 0, 0)");
stmt.executeUpdate("INSERT INTO COFFEES " +
"VALUES ('French_Roast_Decaf', 49, 9.99, 0, 0)");
�Obtener Datos desde una Tabla
Ahora que la tablaCOFFEES tiene valores, podemos escribir una sentencia SELECT para acceder a dichos valores. El asterisco (*) en la siguiente sentencia SQL indica que la columna deber�a ser seleccionada. Como no hay cla�sula WHERE que limite las columas a seleccionar, la siguiente sentencia SQL seleciona la tabla completa.
SELECT * FROM COFFEES
El resultado, que es la tabla completa, se parecer�a a esto.
| COF_NAME | SUP_ID | PRICE | SALES | TOTAL |
|---|---|---|---|---|
| Colombian | 101 | 7.99 | 0 | 0 |
| French_Roast | 49 | 8.99 | 0 | 0 |
| Espresso | 150 | 9.99 | 0 | 0 |
| Colombian_Decaf | 101 | 8.99 | 0 | 0 |
| French_Roast_Decaf | 49 | 9.99 | 0 | 0 |
El resultado anterior es lo que ver�amos en nuestro terminal si introdujeramos la petici�n SQL directamente en el sistema de la base de datos. Cuando accedemos a una base de datos a trav�s de una aplicaci�n Java, como veremos pronto, necesitamos recuperar los resultados para poder utilizarlos. Veremos como hacer esto en la siguiente p�gina.
Aqu� tenemos otro ejemplo de una sentencia SELECT, �sta obtiene una lista de c�fes y sus respectivos precios por libra.
SELECT COF_NAME, PRICE FROM COFFEES
El resultado de esta consulta se parecer�a a esto.
| COF_NAME | ------------------- | PRICE |
|---|---|---|
| Colombian | � |
7.99 |
| French_Roast | � |
8.99 |
| Espresso | � |
9.99 |
| Colombian_Decaf | � |
8.99 |
| French_Roast_Decaf | � |
9.99 |
La sentencia SELECT genera los nombres y precios de todos los c�fes de la tabla. La siguiente sentencia SQL l�mita los caf�s seleccionados a aquellos que cuesten menos de $9.00 por libra.
SELECT COF_NAME, PRICE FROM COFFEES WHERE PRICE < 9.00
El resultado se parecer�a es esto.
| COF_NAME | -------------------- | PRICE |
|---|---|---|
| Colombian | � |
7.99 |
| French_Roast | � |
8.99 |
| Colombian Decaf | � |
8.99 |